package com.ikun.common.validate.validator;

import com.ikun.common.exception.MyException;
import com.ikun.common.validate.anno.*;
import com.ikun.common.validate.constant.RegularPatternType;
import com.ikun.common.validate.group.ValidatorGroup;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Objects;

/**
 * @ClassName Actuator
 * @Description:
 * @CreateDate: 2024/4/20 17:37
 */


public class ValidateExecutor {
    public static <T> void execute(T t, Class<? extends ValidatorGroup> targetGroup) {
        Class<?> aClass = t.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();
        if (Objects.isNull(declaredFields)) {
            throw new RuntimeException("没有字段的类:" + aClass.getTypeName());
        }
        for (Field declaredField : declaredFields) {
            Annotation[] annotations = declaredField.getAnnotations();
            if (Objects.isNull(annotations) || annotations.length == 0) {
                continue;
            }
            //获取值
            StringBuilder methodName = new StringBuilder("get");
            methodName.append(declaredField.getName().substring(0, 1).toUpperCase())
                    .append(declaredField.getName().substring(1, declaredField.getName().length()));
            try {
                Object value = aClass.getMethod(String.valueOf(methodName)).invoke(t);
                handler(value, declaredField, targetGroup);
            } catch (Exception e) {
                throw new MyException(e.getMessage());
            }
        }
    }


    private static void handler(Object value, Field declaredField, Class<?> targetGroup) {
        NotNull notNull = declaredField.getAnnotation(NotNull.class);
        NotBlank notBlank = declaredField.getAnnotation(NotBlank.class);
        Max max = declaredField.getAnnotation(Max.class);
        Min min = declaredField.getAnnotation(Min.class);
        Range range = declaredField.getAnnotation(Range.class);
        Regular regular = declaredField.getAnnotation(Regular.class);
        NotEmpty notEmpty = declaredField.getAnnotation(NotEmpty.class);
        String message;
        Class<?>[] group;

        if (Objects.nonNull(notNull)) {
            message = notNull.message();

            if (Objects.isNull(targetGroup)) {
                //没有分组直接处理
                if (Objects.isNull(value)) {
                    throw new MyException(message);
                }
            } else {
                group = notNull.group();
                if (hasGroup(group, targetGroup)) {
                    if (Objects.isNull(value)) {
                        throw new MyException(message);
                    }
                }
            }

        }
        if (Objects.nonNull(notBlank)) {
            message = notNull.message();

            if (Objects.isNull(value)) {
                throw new MyException(message);
            }

            if (value instanceof String) {
                String val = (String) ((String) value).trim();
                if (Objects.isNull(targetGroup)) {
                    if (Objects.equals(val, "")) {
                        throw new MyException(message);
                    }
                } else {
                    group = notBlank.group();
                    if (hasGroup(group, targetGroup)) {
                        if (Objects.equals(val, "")) {
                            throw new MyException(message);
                        }
                    }
                }
            }
        }
        if (Objects.nonNull(max)) {
            message = max.message();
            if (Objects.isNull(value)) {
                throw new MyException(message);
            }
            double v = Double.parseDouble(value.toString());
            if (Objects.isNull(targetGroup)) {
                if (v > max.value()) {
                    throw new MyException(message);

                }
            } else {
                group = max.group();
                if (hasGroup(group, targetGroup)) {
                    if (v > max.value()) {
                        throw new MyException(message);
                    }
                }
            }
        }
        if (Objects.nonNull(min)) {
            message = min.message();
            group = min.group();

            if (Objects.isNull(value)) {
                throw new MyException(message);
            }
            double v = Double.parseDouble(value.toString());
            if (Objects.isNull(targetGroup)) {
                if (v < min.value()) {
                    throw new MyException(message);
                }
            } else {
                if (hasGroup(group, targetGroup)) {
                    group = min.group();

                    if (hasGroup(group, targetGroup)) {

                        if (v < min.value()) {
                            throw new MyException(message);
                        }
                    }
                }
            }
        }
        if (Objects.nonNull(range)) {
            message = range.message();
            if (Objects.isNull(value)) {
                throw new MyException(message);
            }
            double v = Double.parseDouble(value.toString());

            if (Objects.isNull(targetGroup)) {
                if (v > range.max().value() || v < range.min().value()) {
                    throw new MyException(message);
                }
            } else {
                group = range.group();
                if (hasGroup(group, targetGroup)) {
                    if (v > range.max().value() || v < range.min().value()) {
                        throw new MyException(message);
                    }
                }

            }
        }
        if (Objects.nonNull(regular)) {
            message = regular.message();
            RegularPatternType regularPatternType = regular.pattern();
            String pattern = regularPatternType.getPattern();
            if (Objects.isNull(value) || !(value instanceof String)) {
                throw new MyException(message);
            }
            String val = (String) value;
            if (Objects.isNull(targetGroup)) {
                if (!val.matches(pattern)) {
                    throw new MyException(message);
                }
            } else {
                group = regular.group();
                if (hasGroup(group, targetGroup)) {
                    if (!val.matches(pattern)) {
                        throw new MyException(message);
                    }
                }
            }
        }

    }

    private static Boolean hasGroup(Class<?>[] groups, Class<?> group) {
        return Arrays.asList(groups).contains(group);
    }
}




